<template>
  <view class="file-manager-container">
    <!-- 工具栏 -->
    <view class="toolbar">
      <!-- 第一行：新建文件夹按钮和其他操作按钮 -->
      <view class="toolbar-buttons-row">
        <!-- 左侧：新建文件夹按钮 -->
        <view class="toolbar-left">
          <button v-if="currentPath.length === 1 && canCreateFolder" class="toolbar-btn primary"
            @click="handleAddFolder">
            <uni-icons type="folder-add" size="16" color="#fff"></uni-icons>
            <text class="btn-text">新增文件夹</text>
          </button>
        </view>

        <!-- 右侧：其他操作按钮 -->
        <view class="toolbar-buttons-right">
          <button v-if="currentPath.length > 1" class="toolbar-btn" @click="goBack">
            <uni-icons type="back" size="12" color="#666"></uni-icons>
            <text class="btn-text">返回上一级</text>
          </button>

          <button v-if="currentPath.length > 1 && canUploadFile" class="toolbar-btn success" @click="handleUploadFile">
            <uni-icons type="cloud-upload" size="12" color="#fff"></uni-icons>
            <text class="btn-text">上传文件</text>
          </button>

          <button v-if="selectedItem && selectedItem.type === 'folder'" class="toolbar-btn" @click="openRenameDialog">
            <uni-icons type="compose" size="12" color="#666"></uni-icons>
            <text class="btn-text">重命名</text>
          </button>

          <button v-if="selectedItem && canDelete" class="toolbar-btn danger" @click="deleteSelected">
            <uni-icons type="trash" size="12" color="#fff"></uni-icons>
            <text class="btn-text">删除选中项</text>
          </button>

          <button v-if="selectedFile" class="toolbar-btn" @click="handleFileDetail">
            <uni-icons type="info" size="12" color="#666"></uni-icons>
            <text class="btn-text">详情</text>
          </button>
        </view>
      </view>

      <!-- 第二行：面包屑和搜索 -->
      <view class="toolbar-info-row">
        <!-- 面包屑导航 -->
        <view class="breadcrumb">
          <text v-for="(folder, idx) in currentPath" :key="idx" class="breadcrumb-item">
            <text v-if="idx !== 0" class="breadcrumb-separator"> / </text>
            {{ folder }}
          </text>
        </view>

        <!-- 文件名搜索 -->
        <view v-if="currentPath.length > 1" class="search-box">
          <input class="search-input" v-model="searchFileNameInput" placeholder="搜索文件名"
            @confirm="handleSearchFileName" />
          <button class="search-btn" @click="handleSearchFileName">
            <uni-icons type="search" size="16" color="#fff"></uni-icons>
          </button>
        </view>
      </view>
    </view>

    <!-- 删除文件按钮（单独一行） -->
    <view v-if="selectedFile && canDelete" class="toolbar-delete-row">
      <button class="toolbar-btn danger" @click="handleDeleteFile">
        <uni-icons type="trash" size="12" color="#fff"></uni-icons>
        <text class="btn-text">删除文件</text>
      </button>
    </view>

    <!-- 文件夹列表 -->
    <view v-if="currentPath.length === 1" class="folder-section">
      <view v-if="currentFolder && currentFolder.children && currentFolder.children.length > 0" class="file-list">
        <view v-for="item in pagedFolders" :key="item.id" class="file-item"
          :class="{ selected: selectedItem && selectedItem.id === item.id }" @click="handleSelect(item)"
          @tap="handleDblClick(item)">
          <view class="file-icon">
            <text class="file-icon-text">📁</text>
          </view>
          <view class="file-name">{{ item.name }}</view>
        </view>
      </view>
      <view v-else class="empty-tip">
        暂无文件夹
      </view>

      <!-- 文件夹分页 -->
      <view v-if="currentFolder && currentFolder.children && currentFolder.children.length > 0" class="pagination">
        <button class="page-btn" :disabled="folderPageNum <= 1" @click="folderPageNum = Math.max(1, folderPageNum - 1)">
          上一页
        </button>
        <text class="page-info">{{ folderPageNum }} / {{ Math.ceil(currentFolder.children.length / folderPageSize)
        }}</text>
        <button class="page-btn" :disabled="folderPageNum >= Math.ceil(currentFolder.children.length / folderPageSize)"
          @click="folderPageNum = Math.min(Math.ceil(currentFolder.children.length / folderPageSize), folderPageNum + 1)">
          下一页
        </button>
      </view>
    </view>

    <!-- 子文件夹列表 -->
    <view v-else class="folder-section">
      <view v-if="currentFolder && currentFolder.children && currentFolder.children.length > 0" class="file-list">
        <view v-for="item in pagedFolders" :key="item.id" class="file-item"
          :class="{ selected: selectedItem && selectedItem.id === item.id }" @click="handleSelect(item)"
          @tap="handleDblClick(item)">
          <view class="file-icon">
            <text class="file-icon-text">📁</text>
          </view>
          <view class="file-name">{{ item.name }}</view>
        </view>
      </view>

      <!-- 文件夹分页 -->
      <view v-if="currentFolder && currentFolder.children && currentFolder.children.length > 0" class="pagination">
        <button class="page-btn" :disabled="folderPageNum <= 1" @click="folderPageNum = Math.max(1, folderPageNum - 1)">
          上一页
        </button>
        <text class="page-info">{{ folderPageNum }} / {{ Math.ceil(currentFolder.children.length / folderPageSize)
        }}</text>
        <button class="page-btn" :disabled="folderPageNum >= Math.ceil(currentFolder.children.length / folderPageSize)"
          @click="folderPageNum = Math.min(Math.ceil(currentFolder.children.length / folderPageSize), folderPageNum + 1)">
          下一页
        </button>
      </view>
    </view>

    <!-- 文件列表 -->
    <view v-if="currentPath.length > 1" class="file-section">
      <view v-if="filteredFiles.length > 0" class="project-file-list">
        <view v-for="file in pagedFiles" :key="file.id" class="project-file-item"
          :class="{ selected: selectedFile && selectedFile.id === file.id }" @click="handleFileClick(file)">
          <view class="file-icon">
            <uni-icons :type="getFileIcon(file.fileName)" size="40" :color="getFileColor(file.fileName)"></uni-icons>
          </view>
          <view class="file-name">{{ file.fileName }}</view>
          <view class="file-actions">
            <button class="action-btn" @click.stop="handlePreview(file)">预览</button>
            <!-- <button class="action-btn" @click.stop="handleDownload(file)" v-if="file.downloadUrl">下载</button> -->
          </view>
        </view>
      </view>
      <view v-else class="empty-tip">
        暂无文件
      </view>

      <!-- 文件分页 -->
      <view v-if="filteredFiles.length > 0" class="pagination">
        <button class="page-btn" :disabled="filePageNum <= 1" @click="filePageNum = Math.max(1, filePageNum - 1)">
          上一页
        </button>
        <text class="page-info">{{ filePageNum }} / {{ Math.ceil(filteredFiles.length / filePageSize) }}</text>
        <button class="page-btn" :disabled="filePageNum >= Math.ceil(filteredFiles.length / filePageSize)"
          @click="filePageNum = Math.min(Math.ceil(filteredFiles.length / filePageSize), filePageNum + 1)">
          下一页
        </button>
      </view>
    </view>

    <!-- 新建文件夹弹窗 -->
    <uni-popup ref="folderPopup" type="center">
      <view class="popup-content">
        <view class="popup-header">
          <text class="popup-title">新建文件夹</text>
        </view>
        <view class="popup-body">
          <input class="popup-input" v-model="newFolderName" placeholder="输入文件夹名称" maxlength="50" />
        </view>
        <view class="popup-footer">
          <button class="popup-btn cancel" @click="cancelAddFolder">取消</button>
          <button class="popup-btn confirm" @click="addFolder">确定</button>
        </view>
      </view>
    </uni-popup>

    <!-- 重命名弹窗 -->
    <uni-popup ref="renamePopup" type="center">
      <view class="popup-content">
        <view class="popup-header">
          <text class="popup-title">重命名文件夹</text>
        </view>
        <view class="popup-body">
          <input class="popup-input" v-model="renameFolderName" placeholder="输入新文件夹名称" maxlength="50" />
        </view>
        <view class="popup-footer">
          <button class="popup-btn cancel" @click="cancelRenameFolder">取消</button>
          <button class="popup-btn confirm" @click="renameFolder">确定</button>
        </view>
      </view>
    </uni-popup>

    <!-- 上传文件弹窗 -->
    <uni-popup ref="uploadPopup" type="center">
      <view class="popup-content upload-popup">
        <view class="popup-header">
          <text class="popup-title">上传文件</text>
        </view>
        <view class="popup-body">
          <uni-file-picker v-model="uploadFiles" file-mediatype="all" :limit="10" :auto-upload="false"
            @select="handleFileChange" @delete="handleFileRemove" />

          <!-- 上传进度 -->
          <view v-if="uploadProgress.show" class="upload-progress">
            <view class="progress-header">
              <text class="progress-title">上传进度</text>
              <text class="progress-text">{{ uploadProgress.current }}/{{ uploadProgress.total }}</text>
            </view>
            <view class="progress-bar">
              <view class="progress-fill" :style="{ width: uploadProgress.percentage + '%' }"></view>
            </view>
            <view class="progress-info">
              <text v-if="uploadProgress.currentFile" class="current-file">{{ uploadProgress.currentFile }}</text>
              <text v-if="uploadProgress.status === 'success'" class="upload-success">✓ 上传完成</text>
              <text v-else-if="uploadProgress.status === 'error'" class="upload-error">✗ 上传失败</text>
              <text v-else class="uploading-text">正在上传...</text>
            </view>
          </view>
        </view>
        <view class="popup-footer">
          <button class="popup-btn cancel" @click="cancelUploadFile" :disabled="uploadProgress.show">取消</button>
          <button class="popup-btn confirm" @click="submitUpload" :disabled="uploadProgress.show">上传</button>
        </view>
      </view>
    </uni-popup>

    <!-- 文件详情弹窗 -->
    <uni-popup ref="detailPopup" type="center">
      <view class="popup-content detail-popup">
        <view class="popup-header">
          <text class="popup-title">文件详情</text>
        </view>
        <view class="popup-body">
          <view class="detail-section">
            <view class="detail-row">
              <text class="detail-label">文件名:</text>
              <text class="detail-value">{{ detailFileInfo && detailFileInfo.fileName }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">文件类型:</text>
              <text class="detail-value">{{ detailFileInfo && detailFileInfo.fileType }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">文件大小:</text>
              <text class="detail-value">{{ detailFileInfo && detailFileInfo.fileSize }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">上传人:</text>
              <text class="detail-value">{{ detailFileInfo && detailFileInfo.createBy }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">上传时间:</text>
              <text class="detail-value">{{ detailFileInfo && formatDate(detailFileInfo.createTime) }}</text>
            </view>
          </view>
        </view>
        <view class="popup-footer">
          <button class="popup-btn confirm" @click="closeDetailDialog">关闭</button>
        </view>
      </view>
    </uni-popup>
  </view>
</template>

<script>
import {
  listProjectFolder,
  listProjectFolder2,
  addProjectFolder,
  delProjectFolder,
  updateProjectFolder,
  listProjectFileInfo,
  listProjectFileInfo2,
  delProjectFileInfo,
  addProjectFileInfoByFile,
  addProjectFileInfo2,
  getProjectFileInfo,
  fileLinkTransfer,
  fileLinkLooking
} from '@/api/production/file'

export default {
  name: 'MacosFileManager',
  props: {
    projectId: {
      type: [String, Number],
      required: false,
      default: null
    },
    fileType: {
      type: [String, Number],
      required: false,
      default: null
    },
    folderName: {
      type: String,
      default: ''
    },
    canCreateFolder: {
      type: Boolean,
      default: false
    },
    canUploadFile: {
      type: Boolean,
      default: false
    },
    canDelete: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      root: null,
      currentPath: ['根目录'],
      currentFolder: null,
      showAddFolder: false,
      newFolderName: '',
      selectedItem: null,
      showRenameFolder: false,
      renameFolderName: '',
      showUploadFile: false,
      uploadFiles: [],
      fileList: [],
      selectedFile: null,
      folderPageNum: 1,
      folderPageSize: 10,
      filePageNum: 1,
      filePageSize: 10,
      showDetailDialog: false,
      detailFileInfo: null,
      searchFileName: '',
      searchFileNameInput: '',
      uploadProgress: {
        show: false,
        current: 0,
        total: 0,
        percentage: 0,
        status: '',
        currentFile: ''
      },
      fetchDebounceTimer: null
    }
  },
  computed: {
    pagedFolders() {
      if (!this.currentFolder || !this.currentFolder.children) return []
      const start = (this.folderPageNum - 1) * this.folderPageSize
      return this.currentFolder.children.slice(start, start + this.folderPageSize)
    },
    filteredFiles() {
      if (!this.searchFileName) return this.fileList
      return this.fileList.filter(file =>
        file.fileName && file.fileName.toLowerCase().includes(this.searchFileName.toLowerCase())
      )
    },
    pagedFiles() {
      const start = (this.filePageNum - 1) * this.filePageSize
      return this.filteredFiles.slice(start, start + this.filePageSize)
    }
  },
  watch: {
    projectId() { this.scheduleFetchFolderData() },
    fileType() { this.scheduleFetchFolderData() },
    folderName() { this.scheduleFetchFolderData() },
    currentFolder() {
      this.folderPageNum = 1
    },
    fileList() {
      this.filePageNum = 1
    }
  },
  mounted() {
    this.scheduleFetchFolderData()
  },
  methods: {
    // 合并多次快速触发为一次请求
    scheduleFetchFolderData() {
      if (this.fetchDebounceTimer) {
        clearTimeout(this.fetchDebounceTimer)
      }
      this.fetchDebounceTimer = setTimeout(() => {
        this.fetchFolderData()
        this.fetchDebounceTimer = null
      }, 50)
    },
    // 获取文件夹数据
    async fetchFolderData() {
      if (!this.fileType) return

      try {
        const queryParams = {
          fileType: this.fileType,
          folderName: this.folderName
        }

        // 只有在projectId存在时才添加
        if (this.projectId) {
          queryParams.projectId = this.projectId
        }

        // 当 fileType 为 97 时使用 listProjectFolder2，否则使用 listProjectFolder
        const apiMethod = this.fileType == 97 ? listProjectFolder2 : listProjectFolder
        const res = await apiMethod(queryParams)

        const folders = (res.rows || []).map(item => ({
          id: item.id,
          name: item.folderName,
          type: 'folder',
          children: []
        }))

        this.root = {
          id: 'root',
          name: '根目录',
          type: 'folder',
          children: folders
        }

        this.currentPath = ['根目录']
        this.currentFolder = this.root
        this.selectedItem = null
        this.fetchCurrentFolderFiles()
      } catch (error) {
        console.error('获取文件夹数据失败:', error)
        uni.showToast({
          title: '获取文件夹数据失败',
          icon: 'none'
        })
      }
    },

    // 获取当前文件夹下的文件列表
    async fetchCurrentFolderFiles() {
      const folder = this.currentFolder
      if (!folder || !folder.id || folder.id === 'root') {
        this.fileList = []
        return
      }

      try {
        // 当 fileType 为 97 时使用 listProjectFileInfo2，否则使用 listProjectFileInfo
        const apiMethod = this.fileType == 97 ? listProjectFileInfo2 : listProjectFileInfo
        const res = await apiMethod({ folderId: folder.id })
        this.fileList = res.rows || []
      } catch (error) {
        console.error('获取文件列表失败:', error)
        uni.showToast({
          title: '获取文件列表失败',
          icon: 'none'
        })
      }
    },

    // 选择文件夹
    handleSelect(item) {
      if (this.selectedItem && this.selectedItem.id === item.id) {
        this.selectedItem = null
        this.selectedFile = null
      } else {
        this.selectedItem = item
        this.selectedFile = null
      }
    },

    // 双击进入文件夹
    handleDblClick(item) {
      if (item.type === 'folder') {
        this.currentPath.push(item.name)
        this.currentFolder = item
        this.selectedItem = null
        this.selectedFile = null
        this.fetchCurrentFolderFiles()
      }
    },

    // 返回上一级
    goBack() {
      if (this.currentPath.length <= 1) return

      this.currentPath.pop()

      let folder = this.root
      for (let i = 1; i < this.currentPath.length; i++) {
        folder = folder.children.find(
          c => c.type === 'folder' && c.name === this.currentPath[i]
        )
        if (!folder) break
      }

      this.currentFolder = folder || this.root
      this.selectedItem = null
      this.selectedFile = null
      this.fetchCurrentFolderFiles()
    },

    // 打开新建文件夹弹窗
    handleAddFolder() {
      this.newFolderName = ''
      this.$refs.folderPopup.open()
    },

    // 取消新建文件夹
    cancelAddFolder() {
      this.$refs.folderPopup.close()
    },

    // 新建文件夹
    async addFolder() {
      if (this.currentPath.length !== 1) {
        uni.showToast({
          title: '只能在根目录下新建文件夹',
          icon: 'none'
        })
        return
      }

      const name = this.newFolderName.trim()
      if (!name) {
        uni.showToast({
          title: '文件夹名称不能为空',
          icon: 'none'
        })
        return
      }

      if (this.currentFolder.children.some(c => c.type === 'folder' && c.name === name)) {
        uni.showToast({
          title: '已存在同名文件夹',
          icon: 'none'
        })
        return
      }

      try {
        await addProjectFolder({
          folderName: name,
          projectId: this.projectId,
          fileType: this.fileType
        })

        uni.showToast({
          title: '新建文件夹成功',
          icon: 'success'
        })

        this.$refs.folderPopup.close()
        this.newFolderName = ''
        this.fetchFolderData()
      } catch (error) {
        console.error('新建文件夹失败:', error)
        uni.showToast({
          title: '新建文件夹失败',
          icon: 'none'
        })
      }
    },

    // 删除选中的文件夹
    async deleteSelected() {
      if (!this.selectedItem || this.selectedItem.type !== 'folder') {
        uni.showToast({
          title: '只能删除文件夹',
          icon: 'none'
        })
        return
      }

      const res = await uni.showModal({
        title: '提示',
        content: '确定要删除该文件夹吗？'
      })

      if (!res.confirm) return

      try {
        await delProjectFolder(this.selectedItem.id)
        uni.showToast({
          title: '删除成功',
          icon: 'success'
        })
        this.fetchFolderData()
      } catch (error) {
        console.error('删除失败:', error)
        uni.showToast({
          title: '删除失败',
          icon: 'none'
        })
      }
    },

    // 打开重命名对话框
    openRenameDialog() {
      if (!this.selectedItem || this.selectedItem.type !== 'folder') return
      this.renameFolderName = this.selectedItem.name
      this.$refs.renamePopup.open()
    },

    // 取消重命名
    cancelRenameFolder() {
      this.$refs.renamePopup.close()
    },

    // 打开上传文件弹窗
    handleUploadFile() {
      this.uploadFiles = []
      this.$refs.uploadPopup.open()
    },

    // 取消上传文件
    cancelUploadFile() {
      this.$refs.uploadPopup.close()
    },

    // 关闭详情弹窗
    closeDetailDialog() {
      this.$refs.detailPopup.close()
    },

    // 重命名文件夹
    async renameFolder() {
      const name = this.renameFolderName.trim()
      if (!name) {
        uni.showToast({
          title: '文件夹名称不能为空',
          icon: 'none'
        })
        return
      }

      if (this.currentFolder.children.some(c => c.type === 'folder' && c.name === name && c.id !== this.selectedItem.id)) {
        uni.showToast({
          title: '已存在同名文件夹',
          icon: 'none'
        })
        return
      }

      try {
        await updateProjectFolder({
          id: this.selectedItem.id,
          folderName: name,
          projectId: this.projectId,
          fileType: this.fileType
        })

        uni.showToast({
          title: '重命名成功',
          icon: 'success'
        })

        this.$refs.renamePopup.close()
        this.renameFolderName = ''
        this.fetchFolderData()
      } catch (error) {
        console.error('重命名失败:', error)
        uni.showToast({
          title: '重命名失败',
          icon: 'none'
        })
      }
    },

    // 文件选择
    handleFileClick(file) {
      if (this.selectedFile && this.selectedFile.id === file.id) {
        this.selectedFile = null
      } else {
        this.selectedFile = file
      }
    },

    // 删除文件
    async handleDeleteFile() {
      if (!this.selectedFile) return

      const res = await uni.showModal({
        title: '提示',
        content: '确定要删除该文件吗？'
      })

      if (!res.confirm) return

      try {
        await delProjectFileInfo(this.selectedFile.id)
        uni.showToast({
          title: '删除成功',
          icon: 'success'
        })
        this.selectedFile = null
        this.fetchCurrentFolderFiles()
      } catch (error) {
        console.error('删除失败:', error)
        uni.showToast({
          title: '删除失败',
          icon: 'none'
        })
      }
    },

    // 文件详情
    async handleFileDetail() {
      if (!this.selectedFile) return

      try {
        const res = await getProjectFileInfo(this.selectedFile.id)
        this.detailFileInfo = res.data || res
        this.$refs.detailPopup.open()
      } catch (error) {
        console.error('获取文件详情失败:', error)
        uni.showToast({
          title: '获取文件详情失败',
          icon: 'none'
        })
      }
    },

    // 文件变化
    handleFileChange(event) {
      // uni-file-picker 的 @select 事件返回的数据结构：
      // { tempFiles: [...], tempFilePaths: [...] }
      let fileList = []
      if (event && event.tempFiles) {
        fileList = event.tempFiles
      } else if (Array.isArray(event)) {
        fileList = event
      } else {
        fileList = event.files || event.tempFiles || []
      }

      // 根据 fileType 过滤文件类型（参考PC端逻辑）
      if (this.fileType === 12 || this.fileType === '12') {
        // 只允许图片类型
        const imageExts = ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'svg', 'webp']
        const filtered = fileList.filter(f => {
          const fileName = f.name || f.url || f.path || ''
          const ext = fileName.split('.').pop().toLowerCase()
          return imageExts.includes(ext)
        })
        if (filtered.length < fileList.length) {
          uni.showToast({
            title: '只能上传图片类型文件',
            icon: 'none'
          })
        }
        this.uploadFiles = filtered
      } else if (
        this.fileType === 21 || this.fileType === '21' ||
        this.fileType === 22 || this.fileType === '22'
      ) {
        // 只允许视频类型
        const videoExts = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'webm', 'mpeg', 'mpg']
        const filtered = fileList.filter(f => {
          const fileName = f.name || f.url || f.path || ''
          const ext = fileName.split('.').pop().toLowerCase()
          return videoExts.includes(ext)
        })
        if (filtered.length < fileList.length) {
          uni.showToast({
            title: '只能上传视频类型文件',
            icon: 'none'
          })
        }
        this.uploadFiles = filtered
      } else {
        // 其他类型，允许所有文件
        this.uploadFiles = fileList
      }
      console.log('文件选择完成，文件列表:', this.uploadFiles)
    },

    // 文件移除
    handleFileRemove(file) {
      const index = this.uploadFiles.findIndex(f => f.url === file.url)
      if (index > -1) {
        this.uploadFiles.splice(index, 1)
      }
    },

    // 上传文件
    async submitUpload() {
      if (!this.uploadFiles || this.uploadFiles.length === 0) {
        uni.showToast({
          title: '请选择文件',
          icon: 'none'
        })
        return
      }

      const folder = this.currentFolder
      this.uploadProgress.show = true
      this.uploadProgress.current = 0
      this.uploadProgress.total = this.uploadFiles.length
      this.uploadProgress.percentage = 0
      this.uploadProgress.status = ''
      this.uploadProgress.currentFile = ''

      try {
        // 根据 fileType 选择对应的上传接口（参考PC端逻辑）
        const addFiles = this.fileType == 97 ? addProjectFileInfo2 : addProjectFileInfoByFile

        // 模拟上传进度（参考PC端）
        const simulateProgress = () => {
          return new Promise((resolve) => {
            let progress = 0
            const interval = setInterval(() => {
              progress += Math.random() * 10 + 8 // 随机增加8-18%
              if (progress >= 90) { // 只模拟到90%，留10%给实际上传
                progress = 90
                clearInterval(interval)
                resolve()
              }
              this.uploadProgress.percentage = Math.round(progress)
              const firstFile = this.uploadFiles[0]
              this.uploadProgress.currentFile = firstFile?.name || firstFile?.url || '上传中...'
            }, 150)
          })
        }

        // 先模拟进度到90%
        await simulateProgress()

        // 执行实际上传
        await addFiles({
          files: this.uploadFiles,
          folderId: folder && folder.id,
          fileType: this.fileType,
          projectId: this.projectId
        })

        // 上传完成，进度到100%
        this.uploadProgress.percentage = 100
        this.uploadProgress.status = 'success'
        this.uploadProgress.currentFile = '上传完成'

        // 延迟一下显示成功消息
        setTimeout(() => {
          uni.showToast({
            title: '上传成功',
            icon: 'success'
          })
          this.fetchCurrentFolderFiles()
          this.$refs.uploadPopup.close()
          this.uploadProgress.show = false
          this.uploadFiles = []
        }, 800)

      } catch (error) {
        console.error('上传失败:', error)
        this.uploadProgress.status = 'error'
        this.uploadProgress.currentFile = '上传失败'

        uni.showToast({
          title: error.message || '上传失败',
          icon: 'none',
          duration: 2000
        })

        setTimeout(() => {
          this.uploadProgress.show = false
        }, 2000)
      }
    },

    // 预览文件
    async handlePreview(file) {
      if (!file.downloadUrl) {
        uni.showToast({
          title: '无效的预览链接',
          icon: 'none'
        })
        return
      }

      try {
        let newUrl = ''
        const type = this.getFileIconType(file.fileName)

        if (['image', 'video'].includes(type)) {
          const res = await fileLinkTransfer(file.downloadUrl)
          newUrl = res.data.url
        } else if (['pdf', 'word', 'excel', 'ppt'].includes(type)) {
          // H5/App 用在线预览链接；微信小程序用原文件下载 + openDocument，避免依赖 prvsh.myqcloud.com 业务域名
          // #ifdef MP-WEIXIN
          const transferRes = await fileLinkTransfer(file.downloadUrl)
          newUrl = transferRes.data.url
          // #endif
          // #ifndef MP-WEIXIN
          const lookRes = await fileLinkLooking(file.downloadUrl)
          newUrl = lookRes.data.url
          // #endif
        } else {
          newUrl = file.downloadUrl
        }

        if (!newUrl) {
          uni.showToast({
            title: '获取预览链接失败',
            icon: 'none'
          })
          return
        }

        if (type === 'image') {
          uni.previewImage({
            urls: [newUrl],
            current: newUrl
          })
        } else if (type === 'video') {
          // 小程序端用 previewMedia 预览视频
          uni.previewMedia({
            sources: [{ url: newUrl, type: 'video' }],
            current: 0
          })
        } else if (['pdf', 'word', 'excel', 'ppt'].includes(type)) {
          // #ifdef MP-WEIXIN
          try {
            uni.showLoading({ title: '打开中...', mask: true })
            uni.downloadFile({
              url: newUrl,
              success: (res) => {
                if (res.statusCode === 200) {
                  const fileType = this.getFileIconType(file.fileName)
                  uni.openDocument({
                    filePath: res.tempFilePath,
                    showMenu: true,
                    fileType: fileType === 'word' ? 'doc' : (fileType === 'excel' ? 'xls' : (fileType === 'ppt' ? 'ppt' : 'pdf')),
                    success: () => { },
                    fail: () => {
                      uni.showToast({ title: '打开失败', icon: 'none' })
                    },
                    complete: () => { uni.hideLoading() }
                  })
                } else {
                  uni.hideLoading()
                  uni.showToast({ title: '下载失败', icon: 'none' })
                }
              },
              fail: () => {
                uni.hideLoading()
                uni.showToast({ title: '下载失败', icon: 'none' })
              }
            })
          } catch (e) {
            uni.hideLoading()
            uni.showToast({ title: '打开失败', icon: 'none' })
          }
          // #endif
          // #ifndef MP-WEIXIN
          // 其它端仍用 WebView 打开在线预览
          uni.navigateTo({
            url: `/pages/common/webview/index?url=${encodeURIComponent(newUrl)}&title=${encodeURIComponent(file.fileName)}`
          })
          // #endif
        } else {
          // 其余类型尝试用内置 webview 打开
          uni.navigateTo({
            url: `/pages/common/webview/index?url=${encodeURIComponent(newUrl)}&title=${encodeURIComponent(file.fileName)}`
          })
        }
      } catch (error) {
        console.error('预览失败:', error)
        uni.showToast({
          title: '预览失败',
          icon: 'none'
        })
      }
    },

    // 下载文件
    async handleDownload(file) {
      if (!file.downloadUrl) {
        uni.showToast({
          title: '无效的下载链接',
          icon: 'none'
        })
        return
      }

      try {
        const res = await fileLinkTransfer(file.downloadUrl)
        const newUrl = res.data.url

        if (!newUrl) {
          uni.showToast({
            title: '获取下载链接失败',
            icon: 'none'
          })
          return
        }

        uni.downloadFile({
          url: newUrl,
          success: (res) => {
            if (res.statusCode === 200) {
              uni.showToast({
                title: '下载成功',
                icon: 'success'
              })
            }
          },
          fail: () => {
            uni.showToast({
              title: '下载失败',
              icon: 'none'
            })
          }
        })
      } catch (error) {
        console.error('下载失败:', error)
        uni.showToast({
          title: '下载失败',
          icon: 'none'
        })
      }
    },

    // 搜索文件名
    handleSearchFileName() {
      this.searchFileName = this.searchFileNameInput
      this.filePageNum = 1
    },

    // 获取文件图标类型
    getFileIconType(fileName) {
      if (!fileName) return 'file'
      const ext = fileName.split('.').pop().toLowerCase()
      if (['doc', 'docx'].includes(ext)) return 'word'
      if (['xls', 'xlsx'].includes(ext)) return 'excel'
      if (['ppt', 'pptx'].includes(ext)) return 'ppt'
      if (['pdf'].includes(ext)) return 'pdf'
      if (['png', 'jpg', 'jpeg', 'gif', 'bmp', 'svg', 'webp'].includes(ext)) return 'image'
      if (['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'webm', 'mpeg', 'mpg'].includes(ext)) return 'video'
      if (['txt'].includes(ext)) return 'txt'
      if (['zip', 'rar', '7z', 'tar', 'gz'].includes(ext)) return 'zip'
      return 'file'
    },

    // 获取文件图标
    getFileIcon(fileName) {
      const type = this.getFileIconType(fileName)
      switch (type) {
        case 'word': return 'document'
        case 'excel': return 'document'
        case 'ppt': return 'document'
        case 'pdf': return 'document'
        case 'image': return 'image'
        case 'video': return 'videocam'
        case 'txt': return 'document'
        case 'zip': return 'folder'
        default: return 'document'
      }
    },

    // 获取文件颜色
    getFileColor(fileName) {
      const type = this.getFileIconType(fileName)
      switch (type) {
        case 'word': return '#1890ff'
        case 'excel': return '#52c41a'
        case 'ppt': return '#fa8c16'
        case 'pdf': return '#f5222d'
        case 'image': return '#722ed1'
        case 'video': return '#13c2c2'
        case 'txt': return '#666'
        case 'zip': return '#fa8c16'
        default: return '#666'
      }
    },

    // 格式化日期
    formatDate(dateStr) {
      if (!dateStr) return ''
      const date = new Date(dateStr)
      if (isNaN(date.getTime())) return dateStr

      const year = date.getFullYear()
      const month = String(date.getMonth() + 1).padStart(2, '0')
      const day = String(date.getDate()).padStart(2, '0')
      const hours = String(date.getHours()).padStart(2, '0')
      const minutes = String(date.getMinutes()).padStart(2, '0')
      const seconds = String(date.getSeconds()).padStart(2, '0')

      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
    }
  }
}
</script>

<style lang="scss" scoped>
.file-manager-container {
  padding: 20rpx;
  background: #fff;
  min-height: 100vh;
}

/* 工具栏 */
.toolbar {
  display: flex;
  flex-direction: column;
  gap: 16rpx;
  margin-bottom: 30rpx;
}

.toolbar-buttons-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12rpx;
  width: 100%;
}

.toolbar-left {
  display: flex;
  align-items: center;
  gap: 16rpx;
}

.toolbar-buttons-right {
  display: flex;
  align-items: center;
  gap: 12rpx;
  flex-wrap: wrap;
}

.toolbar-buttons-right .toolbar-btn {
  padding: 6rpx 10rpx;
  font-size: 20rpx;
}

.toolbar-info-row {
  display: flex;
  align-items: center;
  gap: 16rpx;
  justify-content: flex-end;
  width: 100%;
}

.toolbar-delete-row {
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  margin-bottom: 20rpx;
  padding-left: 20rpx;
  width: 100%;
  // border: 1px solid red;
}

.toolbar-delete-row .toolbar-btn {
  margin: 0;
  align-self: flex-start;
  padding: 6rpx 10rpx;
  font-size: 20rpx;
}

.toolbar-delete-row .btn-text {
  font-size: 20rpx;
}

.toolbar-btn {
  display: flex;
  align-items: center;
  padding: 8rpx 14rpx;
  border-radius: 6rpx;
  font-size: 22rpx;
  border: none;
  gap: 4rpx;
  white-space: nowrap;
  flex-shrink: 0;
  min-width: fit-content;

  &.primary {
    background: #1890ff;
    color: #fff;
  }

  &.success {
    background: #52c41a;
    color: #fff;
  }

  &.danger {
    background: #f5222d;
    color: #fff;
  }

  &:not(.primary):not(.success):not(.danger) {
    background: #f5f5f5;
    color: #666;
  }
}

.btn-text {
  font-size: 22rpx;
}

.toolbar-buttons-right .btn-text {
  font-size: 20rpx;
}

/* 面包屑导航 */
.breadcrumb {
  color: #999;
  font-size: 24rpx;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.breadcrumb-item {
  color: #333;
}

.breadcrumb-separator {
  color: #999;
  margin: 0 4rpx;
}

/* 搜索框 */
.search-box {
  display: flex;
  align-items: center;
  gap: 8rpx;
  flex-shrink: 0;
}

.search-input {
  width: 200rpx;
  height: 52rpx;
  padding: 0 14rpx;
  border: 2rpx solid #e5e7eb;
  border-radius: 6rpx;
  font-size: 22rpx;
  background: #f9fafb;
}

.search-btn {
  width: 52rpx;
  height: 52rpx;
  background: #1890ff;
  border-radius: 6rpx;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

/* 文件夹和文件列表 */
.folder-section,
.file-section {
  margin-bottom: 30rpx;
}

.file-list,
.project-file-list {
  display: flex;
  flex-direction: column;
  gap: 8rpx;
  margin-bottom: 20rpx;
}

.file-item,
.project-file-item {
  display: flex;
  flex-direction: row;
  align-items: center;
  width: 100%;
  padding: 20rpx 24rpx;
  border-radius: 8rpx;
  background: #f9fafb;
  transition: all 0.3s ease;
  border: 2rpx solid transparent;

  &:active {
    transform: scale(0.98);
  }

  &.selected {
    border: 2rpx solid #1890ff;
    background: #e6f7ff;
  }

  &:hover {
    background: #f0f0f0;
  }
}

.file-icon {
  margin-right: 20rpx;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.file-icon-text {
  font-size: 32rpx;
  color: #1890ff;
}

.file-name {
  font-size: 28rpx;
  color: #333;
  text-align: left;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-actions {
  display: flex;
  gap: 8rpx;
  margin-top: 16rpx;
  flex-wrap: nowrap;
  justify-content: center;
}

.action-btn {
  padding: 4rpx 10rpx;
  background: #1890ff;
  color: #fff;
  border-radius: 6rpx;
  font-size: 18rpx;
  border: none;
  white-space: nowrap;
  flex-shrink: 0;
}

/* 分页 */
.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20rpx;
  margin-top: 30rpx;
}

.page-btn {
  padding: 8rpx 18rpx;
  background: #f5f5f5;
  color: #666;
  border-radius: 6rpx;
  font-size: 22rpx;
  border: none;

  &:disabled {
    opacity: 0.5;
  }
}

.page-info {
  font-size: 26rpx;
  color: #666;
}

/* 空状态 */
.empty-tip {
  text-align: center;
  color: #999;
  font-size: 28rpx;
  padding: 80rpx 0;
}

/* 弹窗样式 */
.popup-content {
  width: 600rpx;
  background: #fff;
  border-radius: 16rpx;
  overflow: hidden;
}

.popup-header {
  padding: 40rpx 40rpx 20rpx;
  text-align: center;
  border-bottom: 2rpx solid #f0f0f0;
}

.popup-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #333;
}

.popup-body {
  padding: 40rpx;
}

.popup-input {
  width: 100%;
  height: 80rpx;
  padding: 0 20rpx;
  border: 2rpx solid #e5e7eb;
  border-radius: 8rpx;
  font-size: 28rpx;
  background: #f9fafb;
}

.popup-footer {
  display: flex;
  border-top: 2rpx solid #f0f0f0;
}

.popup-btn {
  flex: 1;
  height: 80rpx;
  border: none;
  font-size: 24rpx;

  &.cancel {
    background: #f5f5f5;
    color: #666;
  }

  &.confirm {
    background: #1890ff;
    color: #fff;
  }
}

/* 上传弹窗特殊样式 */
.upload-popup {
  width: 700rpx;
}

.upload-progress {
  margin-top: 30rpx;
  padding: 30rpx;
  background: #f8f9fa;
  border-radius: 8rpx;
  border: 2rpx solid #e9ecef;
}

.progress-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20rpx;
}

.progress-title {
  font-size: 28rpx;
  color: #495057;
}

.progress-text {
  font-size: 24rpx;
  color: #1890ff;
  background: #e6f7ff;
  padding: 4rpx 16rpx;
  border-radius: 24rpx;
}

.progress-bar {
  height: 16rpx;
  background: #e9ecef;
  border-radius: 8rpx;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: #1890ff;
  transition: width 0.3s ease;
}

.progress-info {
  font-size: 26rpx;
  color: #6c757d;
  margin-top: 16rpx;
}

.current-file {
  color: #495057;
  font-weight: 500;
}

.uploading-text {
  color: #1890ff;
  font-weight: 500;
}

.upload-success {
  color: #52c41a;
  font-weight: 500;
}

.upload-error {
  color: #f5222d;
  font-weight: 500;
}

/* 详情弹窗特殊样式 */
.detail-popup {
  width: 700rpx;
}

.detail-section {
  padding: 20rpx 0;
}

.detail-row {
  display: flex;
  align-items: center;
  padding: 20rpx 0;
  border-bottom: 2rpx solid #f0f0f0;

  &:last-child {
    border-bottom: none;
  }
}

.detail-label {
  width: 160rpx;
  font-size: 28rpx;
  color: #666;
  flex-shrink: 0;
}

.detail-value {
  flex: 1;
  font-size: 28rpx;
  color: #333;
  font-weight: 500;
}
</style>
